package cn.hy.preparelesson.module.business;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hy.pms.thrift.SysUserThrift;
import cn.hy.pms.thrift.utils.ThriftUtils;
import cn.hy.preparelesson.common.constant.ProjectConstant;
import cn.hy.preparelesson.common.entity.PlFeedback;
import cn.hy.preparelesson.common.entity.PlFeedbackWithBLOBs;
import cn.hy.preparelesson.common.entity.PlLesson;
import cn.hy.preparelesson.common.enums.SchoolSemesterEnum;
import cn.hy.preparelesson.common.enums.WechatType;
import cn.hy.preparelesson.common.exception.MessageException;
import cn.hy.preparelesson.common.params.PageParams;
import cn.hy.preparelesson.common.permission.RequirePermissions;
import cn.hy.preparelesson.common.service.PlFeedBackService;
import cn.hy.preparelesson.common.utils.*;
import cn.hy.preparelesson.common.vo.*;
import cn.hy.preparelesson.common.service.PlLessonService;
import cn.hy.preparelesson.module.business.vo.PersonFeedbackExportVo;
import cn.hy.preparelesson.module.business.vo.SchoolFeedbackExportVo;
import cn.hy.preparelesson.module.business.vo.SchoolLessonExportVo;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.thrift.TException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 反馈
 */
@RequestMapping("/feedback")
@RestController
public class PlFeedBackController {
    @Autowired
    private PlFeedBackService plFeedBackService;


    @Autowired
    private PlLessonService plLessonService;

    /**
     * 分页获取全校反馈列表
     * @param schoolId
     * @param pageParams
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param distanceYear
     * @param schoolYear
     * @param term
     * @return
     */
    @RequirePermissions("pl:schoolfeedback:list")
    @RequestMapping("/list")
    public Result findSchoolFeedbackValidPageBy(@RequestParam("schoolToken")String schoolId, PageParams pageParams, String title, Date createStartTime,
                                  Date createEndTime, String subjectId, BigDecimal distanceYear,Integer schoolYear, Byte term) throws TException {
        PageInfo<PlFeedback> plFeedbackPageInfo = plFeedBackService.findFeedbackListPageBy(schoolId, pageParams, title, createStartTime, createEndTime,
                subjectId, distanceYear, schoolYear, term, null);
        return Result.success(plFeedbackPageInfo);
    }

    /**
     * 分页获个人反馈
     * @param schoolId
     * @param pageParams
     * @return
     */
    @RequirePermissions("pl:personfeedback:list")
    @RequestMapping("/personList")
    public Result findPersonalFeedbackValidPageBy(@RequestParam("schoolToken")String schoolId, PageParams pageParams, String title, Date createStartTime,
                                                  Date createEndTime, String subjectId, BigDecimal distanceYear,Integer schoolYear, Byte term) throws TException {
        PageInfo<PlFeedback> pageInfo = plFeedBackService.findFeedbackListPageBy(schoolId, pageParams, title, createStartTime, createEndTime,
                subjectId, distanceYear, schoolYear, term, UserUtils.getUserId());
        return Result.success(pageInfo);
    }

    /**
     * 删除反馈
     * @param schoolId
     * @param feedbackId
     * @return
     */
    @RequirePermissions("pl:personfeedback:delete")
    @RequestMapping("/delete")
    public Result deleteFeedback(@RequestParam("schoolToken")String schoolId, String feedbackId) {
        plFeedBackService.softDelete(schoolId, UserUtils.getUserId(), feedbackId);
        return Result.success(null);
    }

    /**
     * 保存修改反馈信息
     * @param schoolId
     * @param plFeedbackSaveVo
     * @return
     */
    @RequirePermissions("pl:personfeedback:addOrEdit")
    @RequestMapping("/saveOrUpdate")
    public Result saveOrUpdate(@RequestParam("schoolToken") String schoolId, PlFeedbackSaveVo plFeedbackSaveVo) throws TException {
        ValidatorUtils.validateEntity(plFeedbackSaveVo);
        List<String> lessonIdList = new ArrayList<>();
        if (StringUtils.isNotBlank(plFeedbackSaveVo.getLessonString())) {
            List<PlLessonIdAndNameVo> plNameAndIdList = JSONObject.parseObject(plFeedbackSaveVo.getLessonString(), new TypeReference<List<PlLessonIdAndNameVo>>(){});
            lessonIdList =  plNameAndIdList.stream().map(PlLessonIdAndNameVo::getLessonId).collect(Collectors.toList());
            validatorPlLesson(schoolId, plNameAndIdList);
        }
        // todo 校验教职工是否存在
        // todo 发送微信消息
        if (StringUtils.isNotBlank(plFeedbackSaveVo.getId())) {
            plFeedBackService.update(schoolId, UserUtils.getUserId(), plFeedbackSaveVo, lessonIdList);
        } else {
            plFeedBackService.save(schoolId, UserUtils.getUserId(), plFeedbackSaveVo, lessonIdList);
        }

        if (plFeedbackSaveVo.getSendToWx() && StringUtils.isNotBlank(plFeedbackSaveVo.getFbToUserIdString())) {
            List<SysUserIdAndNameVo> userByUserIdList = ThriftUtils.findUserNameByUserIdList(Arrays.asList(UserUtils.getUserId()));
            if (!CollectionUtils.isEmpty(userByUserIdList)){
                String userName;
                userName  =   userByUserIdList.get(0).getName();
                sendWxTemplateMsg(schoolId,  plFeedbackSaveVo.getFbToUserIdString().split(","),userName);
            }
        }
        return Result.success(null);
    }

    /**
     * 查询备课详情
     * @param schoolId
     * @param feedbackId
     * @return
     */
    @RequestMapping("/detail")
    public Result findValidDetail(@RequestParam("schoolToken")String schoolId, @RequestParam String feedbackId) throws TException {
        PlFeedbackSaveVo plFeedbackDetail = plFeedBackService.findValidByFeedbackId(schoolId,null, feedbackId);
        return Result.success(plFeedbackDetail);
    }

    /**
     * 校验备课是否存在
     * @param schoolId
     * @param plNameAndIdList
     */
    private  void validatorPlLesson(String schoolId, List<PlLessonIdAndNameVo> plNameAndIdList) {
        List<String> lessonIdList = plNameAndIdList.stream().map(PlLessonIdAndNameVo::getLessonId).collect(Collectors.toList());
        List<PlLesson> plLessonList = plLessonService.findValidLessonListBy(schoolId, null, lessonIdList);
        if(CollectionUtils.isEmpty(plLessonList)) {
            throw new MessageException("备课不存在或已被删除！");
        }
        String lessonName = null;
        for (PlLessonIdAndNameVo plLessonIdAndNameVo : plNameAndIdList) {
            PlLesson plLesson = plLessonList.stream().filter(lesson -> plLessonIdAndNameVo.getLessonId().equals(lesson.getId())).findFirst().orElse(null);
            if (plLesson == null) {
                lessonName = lessonName + plLessonIdAndNameVo.getLessonName() + ",";
            }
        }
        if (StringUtils.isNotBlank(lessonName)) {
            throw new MessageException("备课标题为" + lessonName + "不存在或已被删除");
        }
    }

    /**
     * 导出我的反馈信息
     * @param request
     * @param response
     * @param schoolId
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param distanceYear
     * @param schoolYear
     * @param term
     * @throws TException
     */
    @RequirePermissions("pl:personfeedback:export")
    @RequestMapping("/exportPerson")
    public void exportPersonFeedback(HttpServletRequest request, HttpServletResponse response, @RequestParam("schoolToken")String schoolId, String title, Date createStartTime,
                                     Date createEndTime, String subjectId, BigDecimal distanceYear,Integer schoolYear, Byte term) throws TException{
        PageParams pageParams = new PageParams();
        pageParams.setPageSize(Integer.MAX_VALUE);
        PageInfo<PersonalFeedbackVo> pageInfo = plFeedBackService.findValidPageBy(schoolId, pageParams, title, createStartTime, createEndTime,
                subjectId, distanceYear, schoolYear, term, UserUtils.getUserId());
        List<PersonFeedbackExportVo> exportVoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(pageInfo.getList())) {
            int seq = 1;
            DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            for(PersonalFeedbackVo  feedback : pageInfo.getList()) {
                PersonFeedbackExportVo  exportVo = new PersonFeedbackExportVo();
                exportVo.setSeq(seq ++);
                if (feedback.getSchoolYear() != null && feedback.getTerm() != null) {
                    String currentTerm = feedback.getTerm().equals(SchoolSemesterEnum.ONE.getCode()) ? "一" : "二";
                    int year = feedback.getSchoolYear()+1;
                    exportVo.setSemester(feedback.getSchoolYear() + "年-" + year + "第" + currentTerm + "学期");
                }
                exportVo.setTitle(feedback.getTitle());
                exportVo.setCreateBy(feedback.getCreateByName());
                exportVo.setFbToUser(feedback.getFeedbackTo());
                exportVo.setGrade(feedback.getGradeName());
                exportVo.setSubjectName(feedback.getSubjectName());
                exportVo.setCreateAt(dateFormat.format(feedback.getCreateAt()));
                exportVoList.add(exportVo);
            }
            Workbook sheets = ExcelExportUtil.exportExcel(new ExportParams(null, null, ExcelType.XSSF),
                    PersonFeedbackExportVo.class, exportVoList);
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=" + HttpUtils.getEncodeFileName(request, "我的反馈.xlsx"));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            try (ServletOutputStream outputStream = response.getOutputStream()) {
                sheets.write(outputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 导出全校备课
     * @param request
     * @param response
     * @param schoolId
     * @param title
     * @param createStartTime
     * @param createEndTime
     * @param subjectId
     * @param distanceYear
     * @param schoolYear
     * @param term
     * @throws TException
     */
    @RequirePermissions("pl:schoolfeedback:export")
    @RequestMapping("/exportSchool")
    public void exportSchoolFeedback(HttpServletRequest request, HttpServletResponse response, @RequestParam("schoolToken")String schoolId, String title, Date createStartTime,
                                     Date createEndTime, String subjectId, BigDecimal distanceYear,Integer schoolYear, Byte term) throws TException{
        PageParams pageParams = new PageParams();
        pageParams.setPageSize(Integer.MAX_VALUE);
        PageInfo<PersonalFeedbackVo> pageInfo = plFeedBackService.findValidPageBy(schoolId, pageParams, title, createStartTime, createEndTime,
                subjectId, distanceYear, schoolYear, term, null);
        List<SchoolFeedbackExportVo> exportVoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(pageInfo.getList())) {
            int seq = 1;
            DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            for(PersonalFeedbackVo  feedback : pageInfo.getList()) {
                SchoolFeedbackExportVo  exportVo = new SchoolFeedbackExportVo();
                exportVo.setSeq(seq ++);
                if (feedback.getSchoolYear() != null && feedback.getTerm() != null) {
                    String currentTerm = feedback.getTerm().equals(SchoolSemesterEnum.ONE.getCode()) ? "一" : "二";
                    int year = feedback.getSchoolYear()+1;
                    exportVo.setSemester(feedback.getSchoolYear() + "年-" + year + "第" + currentTerm + "学期");
                }
                exportVo.setTitle(feedback.getTitle());
                exportVo.setCreateBy(feedback.getCreateByName());
                exportVo.setFbToUser(feedback.getFeedbackTo());
                exportVo.setGrade(feedback.getGradeName());
                exportVo.setSubjectName(feedback.getSubjectName());
                exportVo.setCreateAt(dateFormat.format(feedback.getCreateAt()));
                exportVoList.add(exportVo);
            }
            Workbook sheets = ExcelExportUtil.exportExcel(new ExportParams(null, null, ExcelType.XSSF),
                    SchoolFeedbackExportVo.class, exportVoList);
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=" + HttpUtils.getEncodeFileName(request, "全校反馈.xlsx"));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            try (ServletOutputStream outputStream = response.getOutputStream()) {
                sheets.write(outputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发送模板消息
     * @param schoolId
     * @param userIdList
     * @param username
     */
    public void sendWxTemplateMsg(String schoolId,String[] userIdList, String username) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        Map<String, String> params = new HashMap<>(12);
        params.put("schoolId", schoolId);
        params.put("userIds", String.join(",", userIdList));
        params.put("type", String.valueOf(WechatType.GZH.getCode()));
        params.put("templateCommonId", ProjectConstant.templateCommonId);
        params.put("url", null);
        Map<String, String> dataParams = new HashMap<>(8);
        dataParams.put("first", "备课反馈通知");
        dataParams.put("keyword1",  username + "向您提出了课程备课/后记反馈。");
        dataParams.put("keyword2", dateFormat.format(new Date()));
        dataParams.put("remark", "请及时查看");
        params.put("data", JSONObject.toJSONString(dataParams));
        HttpClientUtils.post(ProjectConstant.msgApi + "/pub/wechat/message/template" , params, "UTF-8");
    }
}
